package com.skytech.component.crawler.scratch.base;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Service
public class PageContentService {
    @Autowired
    private PageContentDAO pageContentDAO;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Value("${elasticsearch.server}")
    private String server;
    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    private static final Logger log = LoggerFactory.getLogger(PageContentService.class);
    /**
     * 废弃新闻
     * @param newsId
     * @return
     */
    public boolean abandon(String newsId){
        if(StringUtils.isEmpty(newsId)){
            log.debug("id为空");
            return false;
        }
        String uri = server+"crawler_news/news/"+newsId+"/_update"+"?refresh=true";
        JSONObject param = new JSONObject();
        param.put("abandon","yes");
        JSONObject doc = new JSONObject();
        doc.put("doc",param);

        try {
            restTemplateBuilder.build().postForEntity(uri,doc,JSONObject.class);
        }catch (Exception e){
            log.error(e.getMessage());
            return false;
        }
        return true;

    }

    /**
     * 入库
     * @param newsId
     * @return
     */
    public boolean storage(String newsId){
        if(StringUtils.isEmpty(newsId)){
            log.debug("id为空");
            return false;
        }
        String uri = server+"crawler_news/news/"+newsId+"/_update"+"?refresh=true";
        JSONObject param = new JSONObject();
        param.put("storage","yes");
        JSONObject doc = new JSONObject();
        doc.put("doc",param);

        try {
            restTemplateBuilder.build().postForEntity(uri,doc,JSONObject.class);
        }catch (Exception e){
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 发布新闻
     * @param newsId
     * @return
     */
    public boolean publish(String newsId){
        if(StringUtils.isEmpty(newsId)){
            log.debug("id为空");
            return false;
        }
        String uri = server+"crawler_news/news/"+newsId+"/_update"+"?refresh=true";
        JSONObject param = new JSONObject();
        param.put("publish","yes");
        JSONObject doc = new JSONObject();
        doc.put("doc",param);

        try {
            restTemplateBuilder.build().postForEntity(uri,doc,JSONObject.class);
        }catch (Exception e){
            log.error(e.getMessage());
            return false;
        }
        return true;
    };

    /**
     * 查询新闻
     * @param newsType
     * @param storage
     * @param publish
     * @param beginTime
     * @param endTime
     * @param catalog
     * @param keywords
     * @param pageSize
     * @param pageNo
     * @return
     */
    public JSONObject findPageContentByCondition(String abandon,String newsType, String storage, String publish, String beginTime, String endTime, String catalog, String keywords, Integer pageSize, Integer pageNo){
        if(pageSize ==null)pageSize = 10;
        if(pageNo == null) pageNo = 1;
        String uri = server+"crawler_news/news/_search";
        JSONObject jsonObject = preResolveCondition(abandon,newsType,storage,publish,beginTime,endTime,catalog,keywords,pageSize,pageNo);
        ResponseEntity<JSONObject> forEntity = restTemplateBuilder.build().postForEntity(uri,jsonObject, JSONObject.class);
        JSONArray jsonArray = forEntity.getBody().getJSONObject("hits").getJSONArray("hits");
        JSONObject result = new JSONObject();
        result.put("item",transform(jsonArray));
        result.put("total",forEntity.getBody().getJSONObject("hits").getString("total"));
        result.put("pageSize",pageSize);
        result.put("pageNo",pageNo);
        return result;
    }

    private List<PageView> transform(JSONArray jsonArray){
        List<PageView> list = new ArrayList<>();
        for (Object o : jsonArray) {
            JSONObject jsonObject =  (JSONObject) o;
            PageView pageView = JSON.toJavaObject(jsonObject.getJSONObject("_source"), PageView.class);
            pageView.setId(jsonObject.getString("_id"));
            list.add(pageView);
        }
        return list;

    }

    private JSONObject preResolveCondition(String abandon,String newsType,String storage,String publish,String beginTime,String endTime,String catalog,String keywords,Integer pageSize,Integer pageNo){
        String baseCondition = "{\n" +
                "  \"query\":\n" +
                "  {\n" +
                "    \"bool\": {\n" +
                "      \"must\": [\n" +
                "        {\"match\":{\"target\":\"yes\"}}\n" +
                "      ]\n" +
                "    }\n" +
                "  },\n" +
                "  \"sort\":[{\"timestamp\":{\"order\":\"desc\"}}]\n" +
                "}";
        JSONObject json = JSON.parseObject(baseCondition);

        JSONArray mustJSONArray = json.getJSONObject("query").getJSONObject("bool").getJSONArray("must");

        if(!StringUtils.isEmpty(newsType)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("newsType",newsType);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(abandon)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("abandon",abandon);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(storage)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("storage",storage);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(catalog)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("catalog",catalog);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(publish)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("publish",publish);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        JSONObject filter = new JSONObject();
        if(!StringUtils.isEmpty(beginTime)){
            filter.put("gte",beginTime);
        }
        if(!StringUtils.isEmpty(endTime)){
            filter.put("lte",endTime);
        }
        if(!StringUtils.isEmpty(keywords)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("query",keywords);
            JSONArray jsonArray = new JSONArray();
            jsonArray.add("title");
            jsonArray.add("content");
            jsonObject.put("fields",jsonArray);
            JSONObject must = new JSONObject();
            must.put("multi_match",jsonObject);
            mustJSONArray.add(must);

        }
        if(!filter.isEmpty()){
            JSONObject timestamp = new JSONObject();
            timestamp.put("timestamp",filter);
            JSONObject range = new JSONObject();
            range.put("range",timestamp);
            json.getJSONObject("query").getJSONObject("bool").put("filter",range);
        }


        json.put("from",(pageNo - 1)*pageSize);
        json.put("size",pageSize);
        return json;

    }

    public String count(String abandon,String storage,String publish,String newsType){
        String baseCondition = "{\n" +
                "  \"query\":\n" +
                "  {\n" +
                "    \"bool\": {\n" +
                "      \"must\": [\n" +
                "        {\"match\":{\"target\":\"yes\"}}\n" +
                "      ]\n" +
                "    }\n" +
                "  }\n" +
                "}";
        JSONObject json = JSON.parseObject(baseCondition);
        JSONArray mustJSONArray = json.getJSONObject("query").getJSONObject("bool").getJSONArray("must");
        if(!StringUtils.isEmpty(abandon)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("abandon",abandon);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(storage)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("storage",storage);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(publish)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("publish",publish);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(newsType)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("newsType",newsType);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        String uri = server+"crawler_news/news/_search";
        ResponseEntity<JSONObject> forEntity = restTemplateBuilder.build().postForEntity(uri,json, JSONObject.class);
        return forEntity.getBody().getJSONObject("hits").getString("total");
    }



}
